package com.allqj.sfx.ddd.member.domain.service;

import com.allqj.sfx.ddd.member.domain.entity.flow.FlowApproverType;
import com.allqj.sfx.ddd.member.domain.entity.flow.FlowDef;
import com.allqj.sfx.ddd.member.domain.entity.flow.FlowTaskDef;
import com.allqj.sfx.ddd.member.domain.entity.flow.FlowType;
import com.allqj.sfx.ddd.member.domain.enums.FlowApproverTypeEnum;
import com.allqj.sfx.ddd.member.domain.enums.FlowDefStatusEnum;
import com.allqj.sfx.ddd.member.domain.enums.FlowExceptionEnum;
import com.allqj.sfx.ddd.member.domain.repository.FlowDefRepository;
import com.allqj.sfx.ddd.member.domain.repository.FlowTaskDefRepository;
import com.allqj.sfx.ddd.member.domain.repository.FlowTypeRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sjw
 * @className FlowEngineService
 * @date 2022/7/21 17:56
 * @description: 工作流——任务
 */

@Component
public class FlowService {
    private final FlowTypeRepository flowTypeRepository;
    private final FlowDefRepository flowDefRepository;
    private final FlowTaskDefRepository flowTaskDefRepository;

    public FlowService(FlowTypeRepository flowTypeRepository,
                       FlowDefRepository flowDefRepository,
                       FlowTaskDefRepository flowTaskDefRepository) {
        this.flowTypeRepository = flowTypeRepository;
        this.flowDefRepository = flowDefRepository;
        this.flowTaskDefRepository = flowTaskDefRepository;
    }

    // 模块字典
    public List<FlowType> moduleTypes() {
        return flowTypeRepository.flowTypes(0);
    }

    // 功能字典
    public List<FlowType> functionTypes(Integer moduleId) {
        return flowTypeRepository.flowTypes(moduleId);
    }

    /**
     * 审批类型字典
     *
     * @return
     */
    public List<FlowApproverType> approverTypes() {
        List<FlowApproverType> flowApproverTypes = new ArrayList<>();
        for (FlowApproverTypeEnum flowApproverTypeEnum : FlowApproverTypeEnum.values()
        ) {
            FlowApproverType flowApproverType = new FlowApproverType();
            flowApproverType.setId(flowApproverTypeEnum.getCode());
            flowApproverType.setName(flowApproverTypeEnum.getMessage());
            flowApproverTypes.add(flowApproverType);
        }
        return flowApproverTypes;
    }

    /**
     * 新增流程定义
     *
     * @param flowDef
     * @return
     */
    @Transactional
    public Integer addFlowDef(FlowDef flowDef) {
        if (flowDef == null) return null;
        flowDef.setStatus(FlowDefStatusEnum.DISABLE.getCode());
        List<FlowTaskDef> flowTaskDefs = flowDef.getFlowTaskDefs();
        flowDef = flowDefRepository.save(flowDef);
        Integer flowDefId = flowDef.getId();
        if (flowTaskDefs == null) return flowDefId;
        flowTaskDefs = flowTaskDefs.stream().sorted(Comparator.comparing(FlowTaskDef::getTaskStep)).collect(Collectors.toList());
        int i = 1;
        for (FlowTaskDef flowTaskDef : flowTaskDefs) {
            flowTaskDef.setFlowDefId(flowDefId);
            flowTaskDef.setTaskStep(i);
            i = i + 1;
            flowTaskDef.setOperatorId(flowDef.getOperatorId());
            flowTaskDef.setCreateTime(flowDef.getCreateTime());
            flowTaskDef.setModiferId(flowDef.getModiferId());
            flowTaskDef.setModifyTime(flowDef.getModifyTime());
        }
        flowTaskDefRepository.save(flowTaskDefs);
        return flowDefId;
    }

    /**
     * 修改流程定义
     *
     * @param flowDef
     * @return
     */
    @Transactional
    public Integer modifyFlowDef(FlowDef flowDef) {
        if (flowDef == null || flowDef.getId() == null) return null;
        FlowDef oldFlowFef = flowDefRepository.find(flowDef.getId());
        if (oldFlowFef == null) FlowExceptionEnum.INSTANCE_NOT_EXIST.throwException();
        oldFlowFef.setModuleId(flowDef.getModuleId());
        oldFlowFef.setFunctionId(flowDef.getFunctionId());
        oldFlowFef.setRemark(flowDef.getRemark());
        oldFlowFef.setModifyTime(flowDef.getModifyTime());
        oldFlowFef.setModiferId(flowDef.getModiferId());
        oldFlowFef = flowDefRepository.save(oldFlowFef);
        Integer flowDefId = oldFlowFef.getId();
        // 删除修改前的审批任务定义
        flowTaskDefRepository.deleteByFlowDef(flowDefId);
        List<FlowTaskDef> flowTaskDefs = flowDef.getFlowTaskDefs();
        if (flowTaskDefs == null) return flowDefId;
        flowTaskDefs = flowTaskDefs.stream().sorted(Comparator.comparing(FlowTaskDef::getTaskStep)).collect(Collectors.toList());
        int i = 1;
        for (FlowTaskDef flowTaskDef : flowTaskDefs) {
            flowTaskDef.setFlowDefId(flowDefId);
            flowTaskDef.setTaskStep(i);
            i = i + 1;
            flowTaskDef.setOperatorId(oldFlowFef.getModiferId());
            flowTaskDef.setCreateTime(oldFlowFef.getModifyTime());
            flowTaskDef.setModiferId(oldFlowFef.getModiferId());
            flowTaskDef.setModifyTime(oldFlowFef.getModifyTime());
        }
        flowTaskDefRepository.save(flowTaskDefs);
        return oldFlowFef.getId();
    }
}
